import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.Random;

public class GamePanel extends JPanel implements ActionListener {
    //游戏屏幕的宽，高，每个单元格大小，可以容纳的单元格总数
    static final int SCREEN_WIDTH = 600;
    static final int SCREEN_HEIGHT = 600;
    static final int UNIT_SIZE = 25;
    static final int GAME_UNITS = (SCREEN_WIDTH*SCREEN_HEIGHT)/UNIT_SIZE;
    //定时器延迟，决定游戏速度，数字越大移动越慢
    static final int DELAY = 100;
    //存储蛇身体的坐标
    final int x[] = new int[GAME_UNITS];
    final int y[] = new int[GAME_UNITS];
    //蛇的初始长度
    int bodyParts = 6;
    //吃掉的苹果数量
    int applesEaten;
    //苹果的坐标
    int appleX;
    int appleY;
    //蛇当前的移动方向
    char direction = 'R';
    //游戏是否正在允许
    boolean running = false;
    //控制游戏循环的刷新频率
    Timer timer;
    //生成随机数
    Random random;
    GamePanel(){
        //初始化随机数生成器
        random = new Random();
        //设置面板的尺寸，背景颜色和键盘监听器
        this.setPreferredSize(new Dimension(SCREEN_WIDTH,SCREEN_HEIGHT));
        this.setBackground(Color.BLACK);
        this.setFocusable(true);
        this.addKeyListener(new MyKeyAdapter());
        //启动游戏
        startGame();
    }
    public void startGame(){
        //在屏幕上创建一个新苹果
        newApple();
        //开始游戏
        running = true;
        timer = new Timer(DELAY,this);
        //启动计时器，定时触发actionPerformed()
        timer.start();
    }
    public void paintComponent(Graphics g){
        super.paintComponent(g);
        //每次刷新都会调用draw(g)方法来绘制游戏内容
        draw(g);
    }
    public void draw(Graphics g){
        if (running){
            //画上网格方便观察
            for (int i = 0;i<SCREEN_HEIGHT/UNIT_SIZE;i++){
                g.drawLine(i*UNIT_SIZE,0,i*UNIT_SIZE,SCREEN_HEIGHT);
                g.drawLine(0,i*UNIT_SIZE,SCREEN_WIDTH,i*UNIT_SIZE);
            }
            //画上红色的苹果
            g.setColor(Color.red);
            g.fillOval(appleX,appleY,UNIT_SIZE,UNIT_SIZE);
            //画蛇
            for(int i = 0;i<bodyParts;i++){
                if (i==0){
                    g.setColor(Color.green);
                    g.fillRect(x[i],y[i],UNIT_SIZE,UNIT_SIZE);
                }else{
                    g.setColor(new Color(45,180,0));
                    g.setColor(new Color(random.nextInt(255),random.nextInt(255),random.nextInt(255)));
                    g.fillRect(x[i],y[i],UNIT_SIZE,UNIT_SIZE);
                }
            }
            //画出当前得分
            g.setColor(Color.red);
            g.setFont(new Font("Ink Free",Font.BOLD,40));
            FontMetrics metrics = getFontMetrics(g.getFont());
            g.drawString("Score:"+applesEaten,(SCREEN_WIDTH-metrics.stringWidth("Score:"+applesEaten))/2,g.getFont().getSize());
        }
        else {
            gameOver(g);
        }
    }
    public void newApple(){
        //每当调用newApple()的时候都生成新苹果的坐标
        appleX = random.nextInt((int)(SCREEN_WIDTH/UNIT_SIZE))*UNIT_SIZE;
        appleY = random.nextInt((int)(SCREEN_HEIGHT/UNIT_SIZE))*UNIT_SIZE;
    }
    public void move(){
        //移动蛇
        for (int i =bodyParts;i>0;i--){
            x[i] = x[i-1];
            y[i] = y[i-1];
        }
        switch (direction){
            case 'U':
                y[0] = y[0]- UNIT_SIZE;
                break;
            case 'D':
                y[0] = y[0]+ UNIT_SIZE;
                break;
            case 'L':
                x[0] = x[0]- UNIT_SIZE;
                break;
            case 'R':
                x[0] = x[0]+ UNIT_SIZE;
                break;
        }
    }
    public void checkApple(){
        //检查蛇头是否与苹果重叠
        if((x[0] == appleX)&&(y[0] == appleY)){
            bodyParts++;
            applesEaten++;
            newApple();
        }
    }
    public void checkCollisions(){
        //检查头部是否与身体相撞
        for (int i=bodyParts;i>0;i--){
            if ((x[0]==x[i])&&(y[0]==y[i])){
                running = false;
            }
        }
        //检查头部是否撞到左边界
        if (x[0]<0){
            running = false;
        }
        //检查头部是否撞到有边界
        if (x[0]>SCREEN_WIDTH){
            running = false;
        }
        //检查头部是否撞到上边界
        if (y[0]<0){
            running = false;
        }
        //检查头部是否撞到下边界
        if (y[0]>SCREEN_HEIGHT){
            running = false;
        }
        if (!running){
            timer.stop();
        }
    }
    public void gameOver(Graphics g){
        //最终得分
        g.setColor(Color.red);
        g.setFont(new Font("Ink Free",Font.BOLD,40));
        FontMetrics metrics1 = getFontMetrics(g.getFont());
        g.drawString("Score:"+applesEaten,(SCREEN_WIDTH-metrics1.stringWidth("Score:"+applesEaten))/2,g.getFont().getSize());
        //游戏结束
        g.setColor(Color.red);
        g.setFont(new Font("Ink Free",Font.BOLD,75));
        FontMetrics metrics2 = getFontMetrics(g.getFont());
        g.drawString("Game Over",(SCREEN_WIDTH-metrics2.stringWidth("Game Over"))/2,SCREEN_HEIGHT/2);
    }
    @Override
    public void actionPerformed(ActionEvent e){
        if (running){
            move();
            checkApple();
            checkCollisions();
        }
        repaint();
    }
    public class MyKeyAdapter extends KeyAdapter{
        @Override
        public void keyPressed(KeyEvent e){
            //监听键盘方向键来改变蛇的移动方向
            switch (e.getKeyCode()){
                case KeyEvent.VK_LEFT:
                    if (direction!='R'){
                        direction='L';
                    }
                    break;
                case KeyEvent.VK_RIGHT:
                    if (direction!='L'){
                        direction='R';
                    }
                    break;
                case KeyEvent.VK_UP:
                    if (direction!='D'){
                        direction='U';
                    }
                    break;
                case KeyEvent.VK_DOWN:
                    if (direction!='U'){
                        direction='D';
                    }
                    break;
            }
        }
    }
}
